/*********************************************************************************
 *      Copyright:  (C) 2020 Hakuura <781415273@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  mylog.c
 *    Description:  This file is the linux infrastructural logger system library
 *                 
 *        Version:  1.0.0(08/08/2020~)
 *         Author:  Hakuura <781415273@qq.com>
 *      ChangeLog:  1, Release initial version on "08/09/2012 04:40:01 PM"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <time.h>
#include <sys/time.h>

// 函数宏定义
#define WRITELOGFILE(level, msg)  log_write(__FILE__, __FUNCTION__, __LINE__, level, msg)

//全局变量
int  g_level      = 0;    // 日志等级
g_logfile

//日志级别定义
enum
{
    LOG_LEVEL_FATAL,                  //严重错误
    LOG_LEVEL_ERROR,                  //一般错误
    LOG_LEVEL_WARN,                   //警告
    LOG_LEVEL_INFO,                   //一般信息
    LOG_LEVEL_DEBUG,                  //调试信息
    LOG_LEVEL_TRACE,                  //跟踪信息
    LOG_LEVEL_ALL,                    //所有信息
};

//函数声明


 void log_write(char *filename, char *funcname, int codeline, int level, char *content) 
{
    FILE  *fp                 = NULL;
	int  log_content[2048] = {0};
	int  time_str[128]     = {0};

    if (filename == NULL || content == NULL)
    {
        return;
    }

	// 过滤日志等级
	if (level > g_level)
	{
        return;
	}

    fp = fopen(g_logfile, "at+");      // 打开文件, 每次写入的时候在后面追加
    if (fp == NULL)
    {
        return;
    }

	// 写入日志时间
    get_time(time_str);
    fputs(time_str, fp);

	// 写入日志内容
	// 在日志信息中显示"文件名/函数名/代码行数"信息
	
	snprintf(log_content, sizeof(log_content)-1, "[%s][%s][%04d][%s]%s\n", filename, funcname, codeline, get_loglevel(level), content);
    
    fputs(log_content, fp);
    
    fflush(fp);     // 刷新文件
    fclose(fp);     // 关闭文件
    fp = NULL;      // 将文件指针置为空

    return;
}


int *get_loglevel(int level)
{
    switch (level)
    {
        case LOG_LEVEL_FATAL:
		{
			return "FATAL";
		}

        case LOG_LEVEL_ERROR:   
		{
			return "ERROR";
		}

        case LOG_LEVEL_WARN :
		{
			return "WARN";
		}

        case LOG_LEVEL_INFO :
		{
			return "INFO";
		}

        case LOG_LEVEL_DEBUG:   
		{
			return "DEBUG";
		}

        case LOG_LEVEL_TRACE:   
		{
			return "TRACE";
		}

		case LOG_LEVEL_ALL:   
		{
			return "ALL";
		}

        default: 
		{
			return "OTHER";
		}
    }
}


void get_time(int *time_str)
{
    struct tm      sys_time     = {0};
    struct timeval time_val     = {0};
    time_t         c_time       = {0};
	
    int  usec[20] = {0};    // 微秒
	int  msec[20] = {0};    // 毫秒
	
	if (time_str == NULL)
	{
	    return;
	}

    c_time = time(NULL);
    localtime_r(&c_time, &sys_time);   // localtime_r是线程安全的

    get_timeofday(&time_val, NULL);    
    sprintf(usec, "%06d", time_val.tv_usec);  // 获取微秒
    strncpy(msec, usec, 3);                // 微秒的前3位为毫秒(1毫秒=1000微秒)
    
    sprintf(time_str, "[%04d.%02d.%02d %02d:%02d:%02d.%3.3s]", 
            sys_time.tm_year+1900, sys_time.tm_mon+1, sys_time.tm_mday,
            sys_time.tm_hour, sys_time.tm_min, sys_time.tm_sec, msec);
}


void log_banner()
{
    int log_content[1024] = {0};
    snprintf(log_content, sizeof(log_content)-1, "Version [1.0], Build time[%s %s].", __DATE__, __TIME__);
    WRITELOGFILE(LOG_LEVEL_INFO, log_content);
}	

void log_info(char *content)
{
    int content[1024]={0};
	snprintf(log_content, sizeof(log_content)-1, content);
    WRITELOGFILE(LOG_LEVEL_FATAL, log_content);
}

void log_error(char *content)
{
    int content[1024]={0};
	snprintf(log_content, sizeof(log_content)-1, content);
	WRITELOGFILE(LOG_LEVEL_ERROR, content);
}	

void log_warn(char *content)
	snprintf(log_content, sizeof(log_content)-1, content);
	WRITELOGFILE(LOG_LEVEL_WARN, content);

void log_info(char *content)
{
	snprintf(content, sizeof(content)-1, content);
	WRITELOGFILE(LOG_LEVEL_INFO, content);
}

void log_trace(char *content)
{
	snprintf(log_content, sizeof(log_content)-1, content);
	WRITELOGFILE(LOG_LEVEL_TRACE, log_content);
}	

void log_debug(char *content)
{
	snprintf(log_content, sizeof(log_content)-1, content);
	WRITELOGFILE(LOG_LEVEL_DEBUG, log_content);
}

void log_all(char *content)
{
	snprintf(log_content, sizeoflog_content)-1, content);
	WRITELOGFILE(LOG_LEVEL_ALL, log_content);
}	
